/*******************************************************************************
 * Package: com.practice.annotation
 * Type:    LogAspact
 * Date:    2024/3/8 17:26
 *
 * Copyright (c) 2024 BOING CORP.,LTD All Rights Reserved.
 *
 * You may not use this file except in compliance with the License.
 *******************************************************************************/
package com.practice.annotation;

import com.practice.pojo.entity.Log;
import com.practice.service.LogService;
import com.practice.utils.MyIdGenerator;
import com.practice.utils.SecurityUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Date;

/**
 * TODO your comment
 *
 * @author Masiyu
 * @date 2024/3/8 17:26
 */
@Component
@Aspect
@Transactional
public class LogAspect {
    /**
     * 主键生成器
     */
    @Autowired
    private MyIdGenerator idGenerator;
    
    @Autowired
    private LogService logService;
    
    @Pointcut("@annotation(com.practice.annotation.LogSaver)")
    public void logPointCut() {
    }
    
    @AfterThrowing(pointcut = "logPointCut()", throwing = "ex")
    public void doAfterThrowingTask(Exception ex) {
    
    }
    
    @Around("logPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        Log log = new Log();
        Object result = null;
        try {
            MethodSignature signature = (MethodSignature) point.getSignature();
            Method method = signature.getMethod();
            //方法参数
            String args = Arrays.toString(point.getArgs());
            //注解信息
            LogSaver logSaver = method.getAnnotation(LogSaver.class);
            
            if (SecurityUtils.getLoginInfo() != null) {
                //用户id
                Long userId = SecurityUtils.getLoginInfo().getId();
                log.setUserId(userId);
                log.setUserName(SecurityUtils.getLoginInfo().getName());
            }
            log.setId(idGenerator.snowflakeId());
            log.setCreateTime(new Date());
            log.setMethodName(logSaver.value());
            log.setType(logSaver.operationType());
            if (args.length() > 5000) {
                args = args.substring(0, 5000);
            }
            log.setMethodParam(args);
            result = point.proceed();
        } catch (Throwable e) {
            logService.save(log);
            throw e;
        }
        logService.save(log);
        return result;
    }
}
